package com.may.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

/**
 * @program: com.may.netty
 * @description: buffer 的分散和聚合
 * @author: Bobby.Ma
 * @create: 2020-08-02 17:19
 * <p>
 * Scattering：将数据写入 buffer 时，可以采用 buffer 数组，依次分散写入；
 * Gathering：从 buffer 读取数据时，可以采用 buffer 依次读取。
 * <p>
 * 服务端会将客户端发送来的数据依次写入到 buffer 数组，然后再依次读取 buffer 数组。适合数据量大的情况。
 **/
public class ScatteringAndGatheringTest {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        InetSocketAddress inetSocketAddress = new InetSocketAddress(8888);
        serverSocketChannel.socket().bind(inetSocketAddress);

        //创建一个 ByteBuffer 数组
        ByteBuffer[] buffers = new ByteBuffer[2];
        buffers[0] = ByteBuffer.allocate(5);
        buffers[1] = ByteBuffer.allocate(3);

        SocketChannel socketChannel = serverSocketChannel.accept();
        int msgLength = 8;
        while (true) {
            int read = 0;
            while (read < msgLength) {
                long l = socketChannel.read(buffers);
                read += l;
                Arrays.stream(buffers).forEach(byteBuffer -> System.out.println(String.format("position: %d , limit: %d", byteBuffer.position(), byteBuffer.limit())));
            }

            //将所有的 buffer 进行 flip
            Arrays.stream(buffers).forEach(ByteBuffer::flip);
            //返回数据到客户端
            int write = 0;
            while (write < msgLength) {
                long l = socketChannel.write(buffers);
                write += l;
            }

            Arrays.stream(buffers).forEach(ByteBuffer::clear);

            System.out.println(String.format("read: %d , write: %d , msgLength: %d", read, write, msgLength));
        }
    }
}


